-- Lua Battle System - 决策树
-- 实现决策树的核心功能，包括决策节点定义、条件判断和决策执行

local Logger = require("utils.logger")
local TableUtils = require("utils.table_utils")

-- 决策树节点基类
local DecisionTreeNode = {
    id = "",
    name = "",
    type = "", -- condition, action, leaf
    parent = nil,
    children = {},
    priority = 0
}

-- 决策树节点构造函数
function DecisionTreeNode:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

-- 条件节点类
local ConditionNode = DecisionTreeNode:new()
ConditionNode.type = "condition"
ConditionNode.condition = nil
ConditionNode.true_child = nil
ConditionNode.false_child = nil

-- 条件节点构造函数
function ConditionNode:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    o.children = {}
    return o
end

-- 执行条件判断
function ConditionNode:evaluate(character, battle_state)
    if not self.condition then
        Logger.error("条件节点缺少条件判断函数")
        return false
    end
    
    local result = self.condition(character, battle_state)
    return result
end

-- 动作节点类
local ActionNode = DecisionTreeNode:new()
ActionNode.type = "action"
ActionNode.action = nil

-- 动作节点构造函数
function ActionNode:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

-- 执行动作
function ActionNode:execute(character, battle_state)
    if not self.action then
        Logger.error("动作节点缺少动作执行函数")
        return nil
    end
    
    local result = self.action(character, battle_state)
    return result
end

-- 叶子节点类
local LeafNode = DecisionTreeNode:new()
LeafNode.type = "leaf"
LeafNode.decision = nil

-- 叶子节点构造函数
function LeafNode:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

-- 决策树类
local DecisionTree = {
    id = "",
    name = "",
    root = nil,
    version = "1.0"
}

-- 决策树构造函数
function DecisionTree:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

-- 设置根节点
function DecisionTree:set_root(node)
    self.root = node
    Logger.info("决策树根节点已设置: " .. node.name)
end

-- 添加节点
function DecisionTree:add_node(parent, child)
    if not parent or not child then
        Logger.error("父节点或子节点不能为空")
        return false
    end
    
    table.insert(parent.children, child)
    child.parent = parent
    return true
end

-- 评估决策树
function DecisionTree:evaluate(character, battle_state)
    if not self.root then
        Logger.error("决策树没有根节点")
        return nil
    end
    
    return self:evaluate_node(self.root, character, battle_state)
end

-- 评估节点
function DecisionTree:evaluate_node(node, character, battle_state)
    if node.type == "condition" then
        -- 条件节点
        local result = node:evaluate(character, battle_state)
        if result then
            -- 条件为真，执行真分支
            if node.true_child then
                return self:evaluate_node(node.true_child, character, battle_state)
            end
        else
            -- 条件为假，执行假分支
            if node.false_child then
                return self:evaluate_node(node.false_child, character, battle_state)
            end
        end
    elseif node.type == "action" then
        -- 动作节点
        return node:execute(character, battle_state)
    elseif node.type == "leaf" then
        -- 叶子节点，返回决策
        return node.decision
    end
    
    return nil
end

-- 构建简单的攻击决策树
function DecisionTree:build_attack_tree()
    -- 根节点：是否有可用技能
    local root = ConditionNode:new({
        id = "root",
        name = "是否有可用技能",
        condition = function(character, battle_state)
            for _, skill in ipairs(character.skills) do
                if skill:is_usable(character) then
                    return true
                end
            end
            return false
        end
    })
    
    -- 技能可用分支：是否有低生命值敌人
    local has_low_hp_enemies = ConditionNode:new({
        id = "has_low_hp_enemies",
        name = "是否有低生命值敌人",
        condition = function(character, battle_state)
            for _, enemy in ipairs(battle_state.characters) do
                if enemy.team_id ~= character.team_id and enemy.is_alive then
                    local health_percentage = enemy.hp / enemy.max_hp
                    if health_percentage < 0.3 then
                        return true
                    end
                end
            end
            return false
        end
    })
    
    -- 有低生命值敌人：使用高伤害技能攻击
    local attack_low_hp_enemy = LeafNode:new({
        id = "attack_low_hp_enemy",
        name = "攻击低生命值敌人",
        decision = {
            type = "skill",
            priority = 100,
            strategy = "attack_lowest_hp"
        }
    })
    
    -- 没有低生命值敌人：是否有高威胁敌人
    local has_high_threat_enemies = ConditionNode:new({
        id = "has_high_threat_enemies",
        name = "是否有高威胁敌人",
        condition = function(character, battle_state)
            for _, enemy in ipairs(battle_state.characters) do
                if enemy.team_id ~= character.team_id and enemy.is_alive then
                    if enemy.attack > character.defense * 1.5 then
                        return true
                    end
                end
            end
            return false
        end
    })
    
    -- 有高威胁敌人：使用控制技能
    local use_control_skill = LeafNode:new({
        id = "use_control_skill",
        name = "使用控制技能",
        decision = {
            type = "skill",
            priority = 90,
            strategy = "use_control_skill"
        }
    })
    
    -- 没有高威胁敌人：使用普通攻击
    local use_normal_attack = LeafNode:new({
        id = "use_normal_attack",
        name = "使用普通攻击",
        decision = {
            type = "skill",
            priority = 80,
            strategy = "use_normal_attack"
        }
    })
    
    -- 没有可用技能：是否可以使用物品
    local has_usable_items = ConditionNode:new({
        id = "has_usable_items",
        name = "是否可以使用物品",
        condition = function(character, battle_state)
            for item_id, quantity in pairs(character.items) do
                if quantity > 0 then
                    local ItemManager = require("items.item_manager")
                    local item = ItemManager:get_item(item_id)
                    if item and item:is_usable("battle") then
                        return true
                    end
                end
            end
            return false
        end
    })
    
    -- 可以使用物品：使用恢复物品
    local use_item = LeafNode:new({
        id = "use_item",
        name = "使用恢复物品",
        decision = {
            type = "item",
            priority = 70,
            strategy = "use_healing_item"
        }
    })
    
    -- 没有可用物品：防御
    local defend = LeafNode:new({
        id = "defend",
        name = "防御",
        decision = {
            type = "defend",
            priority = 60
        }
    })
    
    -- 构建树结构
    root.true_child = has_low_hp_enemies
    root.false_child = has_usable_items
    has_low_hp_enemies.true_child = attack_low_hp_enemy
    has_low_hp_enemies.false_child = has_high_threat_enemies
    has_high_threat_enemies.true_child = use_control_skill
    has_high_threat_enemies.false_child = use_normal_attack
    has_usable_items.true_child = use_item
    has_usable_items.false_child = defend
    
    self.root = root
    Logger.info("攻击决策树构建完成")
end

-- 构建简单的防御决策树
function DecisionTree:build_defense_tree()
    -- 根节点：自身生命值是否低
    local root = ConditionNode:new({
        id = "root",
        name = "自身生命值是否低",
        condition = function(character, battle_state)
            local health_percentage = character.hp / character.max_hp
            return health_percentage < 0.3
        end
    })
    
    -- 生命值低：是否有治疗技能
    local has_heal_skill = ConditionNode:new({
        id = "has_heal_skill",
        name = "是否有治疗技能",
        condition = function(character, battle_state)
            for _, skill in ipairs(character.skills) do
                if skill.healing.base > 0 and skill:is_usable(character) then
                    return true
                end
            end
            return false
        end
    })
    
    -- 有治疗技能：使用治疗技能
    local use_heal_skill = LeafNode:new({
        id = "use_heal_skill",
        name = "使用治疗技能",
        decision = {
            type = "skill",
            priority = 100,
            strategy = "use_heal_skill"
        }
    })
    
    -- 没有治疗技能：是否有治疗物品
    local has_heal_item = ConditionNode:new({
        id = "has_heal_item",
        name = "是否有治疗物品",
        condition = function(character, battle_state)
            for item_id, quantity in pairs(character.items) do
                if quantity > 0 then
                    local ItemManager = require("items.item_manager")
                    local item = ItemManager:get_item(item_id)
                    if item and item.type == "consumable" and item.effects.healing then
                        return true
                    end
                end
            end
            return false
        end
    })
    
    -- 有治疗物品：使用治疗物品
    local use_heal_item = LeafNode:new({
        id = "use_heal_item",
        name = "使用治疗物品",
        decision = {
            type = "item",
            priority = 90,
            strategy = "use_healing_item"
        }
    })
    
    -- 没有治疗物品：防御
    local defend = LeafNode:new({
        id = "defend",
        name = "防御",
        decision = {
            type = "defend",
            priority = 80
        }
    })
    
    -- 生命值不低：是否有队友生命值低
    local has_low_hp_allies = ConditionNode:new({
        id = "has_low_hp_allies",
        name = "是否有队友生命值低",
        condition = function(character, battle_state)
            for _, ally in ipairs(battle_state.characters) do
                if ally.team_id == character.team_id and ally.is_alive and ally.id ~= character.id then
                    local health_percentage = ally.hp / ally.max_hp
                    if health_percentage < 0.3 then
                        return true
                    end
                end
            end
            return false
        end
    })
    
    -- 有队友生命值低：是否有治疗技能
    local has_ally_heal_skill = ConditionNode:new({
        id = "has_ally_heal_skill",
        name = "是否有治疗技能",
        condition = function(character, battle_state)
            for _, skill in ipairs(character.skills) do
                if skill.healing.base > 0 and skill:is_usable(character) then
                    return true
                end
            end
            return false
        end
    })
    
    -- 有治疗技能：治疗队友
    local heal_ally = LeafNode:new({
        id = "heal_ally",
        name = "治疗队友",
        decision = {
            type = "skill",
            priority = 95,
            strategy = "heal_lowest_hp_ally"
        }
    })
    
    -- 没有治疗技能：是否有辅助技能
    local has_support_skill = ConditionNode:new({
        id = "has_support_skill",
        name = "是否有辅助技能",
        condition = function(character, battle_state)
            for _, skill in ipairs(character.skills) do
                if skill.type == "support" and skill:is_usable(character) then
                    return true
                end
            end
            return false
        end
    })
    
    -- 有辅助技能：使用辅助技能
    local use_support_skill = LeafNode:new({
        id = "use_support_skill",
        name = "使用辅助技能",
        decision = {
            type = "skill",
            priority = 85,
            strategy = "use_support_skill"
        }
    })
    
    -- 没有辅助技能：正常攻击
    local normal_attack = LeafNode:new({
        id = "normal_attack",
        name = "正常攻击",
        decision = {
            type = "skill",
            priority = 80,
            strategy = "normal_attack"
        }
    })
    
    -- 构建树结构
    root.true_child = has_heal_skill
    root.false_child = has_low_hp_allies
    has_heal_skill.true_child = use_heal_skill
    has_heal_skill.false_child = has_heal_item
    has_heal_item.true_child = use_heal_item
    has_heal_item.false_child = defend
    has_low_hp_allies.true_child = has_ally_heal_skill
    has_low_hp_allies.false_child = has_support_skill
    has_ally_heal_skill.true_child = heal_ally
    has_ally_heal_skill.false_child = has_support_skill
    has_support_skill.true_child = use_support_skill
    has_support_skill.false_child = normal_attack
    
    self.root = root
    Logger.info("防御决策树构建完成")
end

-- 导出模块
local DecisionTreeModule = {
    DecisionTreeNode = DecisionTreeNode,
    ConditionNode = ConditionNode,
    ActionNode = ActionNode,
    LeafNode = LeafNode,
    DecisionTree = DecisionTree
}

return DecisionTreeModule